#!/usr/bin/env bash

# This line is a comment, the line at the top is not.
# map generator ContinentGen Bash script.sh v1.8

# Declare variables
declare    zeroPad="0000" tile test
declare -a terrain_layer terrain_layer_B
declare -i x y c=0 r blanklines maxgap=12

# The map size is determined by the xsize and ysize variables on the next line
declare -i xsize=120 ysize=60

# The # of rectangles is set in the variable rectangles, below.
# Valid values are 1, 2, -2, 4, 6, -6, 8, -8, 9, and 16.
# 2 gives 2 vertical continents, -2 gives 2 horizontal, similar for 6, -6, and 8, -8

declare -i rectangles=8

# maxgap controls how many contiguous blank horizontal lines
# are allowed in the map before looping stops.
# The map dimensions also effect the shape and size of each continent.
if [ ${rectangles} -eq 1 ] ; then
	maxgap=12
elif [ ${rectangles} -eq 2 ] ; then
	maxgap=10
elif [ ${rectangles} -eq -2 ] ; then
	maxgap=10
elif [ ${rectangles} -eq 4 ] ; then
	maxgap=10
elif [ ${rectangles} -eq 6 ] ; then
	maxgap=10
elif [ ${rectangles} -eq 8 ] ; then
	maxgap=7
elif [ ${rectangles} -eq -8 ] ; then
	maxgap=7
elif [ ${rectangles} -eq 9 ] ; then
	maxgap=12
elif [ ${rectangles} -eq 16 ] ; then
	maxgap=12
fi

# Ouput a blank line
echo

# Create terrain layer
for (( y=0 ; y<${ysize} ; y++ )) ; do
	for (( x=0 ; x<${xsize} ; x++ )) ; do

		r=$(( 1 + RANDOM % 19 ))

		# No lake tiles, add them later
		if [ ${r} -ge 1 ] && [ ${r} -le 5 ] ; then tile="g" ; fi
		if [ ${r} -ge 6 ] && [ ${r} -le 9 ] ; then tile="p" ; fi
		if [ ${r} -ge 10 ] && [ ${r} -le 12 ] ; then tile="h" ; fi
		if [ ${r} -ge 13 ] && [ ${r} -le 15 ] ; then tile="f" ; fi
		if [ ${r} -eq 16 ] ; then tile="m" ; fi
		if [ ${r} -eq 17 ] ; then tile="d" ; fi
		if [ ${r} -eq 18 ] ; then tile="j" ; fi
		if [ ${r} -eq 19 ] ; then tile="s" ; fi


		if [ ${rectangles} -eq 1 ] ; then
			# No divisions, 1 supercontinent
			:
		elif [ ${rectangles} -eq 2 ] ; then
			# 1 row of ocean vertical middle centerline
			if [ ${x} -eq $(( ${xsize} / 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq -2 ] ; then
			# 1 row of ocean horizontal middle centerline
			if [ ${y} -eq $(( ${ysize} / 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq 4 ] ; then
			# 1 column of ocean vertical middle centerine
			if [ ${x} -eq $(( ${xsize} / 2 )) ] ; then tile=" " ; fi
			# 1 row of ocean horizontal middle centerline
			if [ ${y} -eq $(( ${ysize} / 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq 6 ] ; then
			# 2 columns of ocean vertical
			if [ ${x} -eq $(( ${xsize} / 3 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ${xsize} / 3 * 2 )) ] ; then tile=" " ; fi
			# 1 row of ocean horizontal middle centerline
			if [ ${y} -eq $(( ${ysize} / 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq -6 ] ; then
			# 1 column of ocean vertical
			if [ ${x} -eq $(( ${xsize} / 2 )) ] ; then tile=" " ; fi
			# 2 rows of ocean horizontal
			if [ ${y} -eq $(( ${ysize} / 3 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ${ysize} / 3 * 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq 8 ] ; then
			# 3 columns of ocean vertical
			if [ ${x} -eq $(( ${xsize} / 4 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ${xsize} / 4 * 2 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ${xsize} / 4 * 3 )) ] ; then tile=" " ; fi
			# 1 row of ocean horizontal middle centerline
			if [ ${y} -eq $(( ${ysize} / 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq -8 ] ; then
			# 1 column of ocean vertical middle centerine
			if [ ${x} -eq $(( ${xsize} / 2 )) ] ; then tile=" " ; fi
			# 3 rows of ocean horizontal middle centerline
			if [ ${y} -eq $(( ${ysize} / 4 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ${ysize} / 4 * 2 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ${ysize} / 4 * 3 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq 9 ] ; then
			# 1 column of ocean vertical per 1/3rd of map
			if [ ${x} -eq $(( ${xsize} / 3 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ( ${xsize} / 3 ) * 2 )) ] ; then tile=" " ; fi
			# 1 row of ocean horizontal per 1/3rd of map
			if [ ${y} -eq $(( ${ysize} / 3 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ( ${ysize} / 3 ) * 2 )) ] ; then tile=" " ; fi
		elif [ ${rectangles} -eq 16 ] ; then
			# 1 column of ocean vertical per 1/4 of map
			if [ ${x} -eq $(( ${xsize} / 4 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ( ${xsize} / 4 ) * 2 )) ] ; then tile=" " ; fi
			if [ ${x} -eq $(( ( ${xsize} / 4 ) * 3 )) ] ; then tile=" " ; fi
			# 1 row of ocean horizontal per 1/4 of map
			if [ ${y} -eq $(( ${ysize} / 4 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ( ${ysize} / 4 ) * 2 )) ] ; then tile=" " ; fi
			if [ ${y} -eq $(( ( ${ysize} / 4 ) * 3 )) ] ; then tile=" " ; fi
		fi

		# 1 row of ocean at map edges left, right, top, bottom
		if [ ${x} -eq 0  ] ; then tile=" " ; fi
		if [ ${y} -eq 0  ] ; then tile=" " ; fi
		if [ ${x} -eq $(( ${xsize} - 1 )) ] || [ ${y} -eq $(( ${ysize} - 1 )) ] ; then tile=" " ; fi

		terrain_layer[${y}]="${terrain_layer[${y}]}${tile}"
	done
done

# output original rectangles
echo "Before the loops:"
for ((y=0;y<${ysize};y++)) ; do
	echo "t${zeroPad:${#y}}${y}=\"${terrain_layer[${y}]}\""
done


# Now loop top-to-bottom and bottom-to-top through the lines
# and look for land tiles next to ocean
# and change some of the land tiles to ocean too
# and output the map after each loop

# Loops up to 16 times, but stops if there are too many blank lines

for (( loop=1 ; loop<=18 ; loop++ )) ; do

	test=""
	blanklines=0
	echo ; echo

	# print loop header with loop #
	echo "loop: ${loop}"

	for (( z=0; z<${ysize} ; z++ )) ; do

		if [ $(( loop % 2 )) -eq 0 ] ; then
			# even loop number, loop backward, ysize to 0
			y=$(( ysize - z ))
		else
			# odd loop number, loop forward, 0 to ysize
			y=z
		fi

		terrain_layer_B[${y}]=""

		for (( x=0 ; x<${xsize} ; x++ )) ; do

			# This is the tile which we might change from land to ocean
			tile="${terrain_layer[${y}]:${x}:1}"

			# If this tile is not ocean then check the tiles around it
			if [ "${tile}" != " " ] ; then

				# Next are the 8 tiles of the ring around that tile

				# above the tile
				if [ "${terrain_layer[$((${y}-1))]:$((${x}-1)):1}" == " " ] ; then c=$((c+1)) ; fi
				if [ "${terrain_layer[$((${y}-1))]:${x}:1}" == " " ] ; then c=$((c+1)) ; fi
				if [ "${terrain_layer[$((${y}-1))]:$((${x}+1)):1}" == " " ] ; then c=$((c+1)) ; fi

				# beside the tile
				if [ "${terrain_layer[${y}]:$((${x}-1)):1}" == " " ] ; then c=$((c+1)) ; fi
				if [ "${terrain_layer[${y}]:$((${x}+1)):1}" == " " ] ; then c=$((c+1)) ; fi

				# below the tile
				if [ "${terrain_layer[$((${y}+1))]:$((${x}-1)):1}" == " " ] ; then c=$((c+1)) ; fi
				if [ "${terrain_layer[$((${y}+1))]:${x}:1}" == " " ] ; then c=$((c+1)) ; fi
				if [ "${terrain_layer[$((${y}+1))]:$((${x}+1)):1}" == " " ] ; then c=$((c+1)) ; fi

				if [ "${tile}" != " " ] ; then
					# If only 1 neighboring tile is ocean,
					# then only a small chance of changing the tile to ocean
					if [ "${c}" -eq 1 ] ; then
						if [ $(( 1 + RANDOM % 10 )) -ge 9 ] ; then
							tile=" "
						fi
					# If 2 neighboring tiles are ocean, slightly better chance
					elif [ "${c}" -eq 2 ] ; then
						if [ $(( 1 + RANDOM % 10 )) -ge 8 ] ; then
							tile=" "
						fi
					# If 3 neighboring tiles are ocean, an even better chance
					elif [ "${c}" -eq 3 ] ; then
						if [ $(( 1 + RANDOM % 10 )) -ge 7 ] ; then
							tile=" "
						fi
					# If more than 3 neighboring tiles are ocean,
					# then change this one to ocean too
					elif [ "${c}" -gt 3 ] ; then
						tile=" "
					fi
				fi
			fi
			c=0
			terrain_layer_B[${y}]="${terrain_layer_B[${y}]}${tile}"
		done
		terrain_layer[${y}]="${terrain_layer_B[${y}]}"

# track percentage of map that is land tiles?

		# if a significant portion of the map lines are blank on this loop, then break
		test="${terrain_layer[${y}]// /}"
		if [ "${#test}" -eq 0 ] ; then
			blanklines=$(( ${blanklines} + 1 ))
		else
			blanklines=0
		fi

		if [ ${blanklines} -gt ${maxgap} ] ; then
			echo "Loop ${loop} aborted due to # of blank lines=${blanklines}"
			break 3
		fi
	done

	# This would be a good place to add lake tiles

	for ((y=0;y<${ysize};y++)) ; do
		echo "t${zeroPad:${#y}}${y}=\"${terrain_layer_B[${y}]}\""
	done
done

# Print 1 last blank line
echo

exit 0